<?php

/**
 * Description of router
 *
 * @author user
 */
class Router {

    public $segments = array();
    public $controller;
    private $controller_obj;
    public $method;
    public $vars = array();
    private static $instance;

    /**
     * Constructor
     */
    public function __construct() {
        self::$instance = $this;
        $this->_set_uri();
        $this->_set_controller();
        $this->_set_method();
        $this->_set_vars();

        // Let controller know router
        $this->controller_obj->router = & $this;
    }

    /**
     * Get URI Request
     */
    private function _set_uri() {
        include BASEPATH . 'config/config.php';
        $path_info = "";
        if (isset($_SERVER['PATH_INFO'])) {
            $path_info = $_SERVER['PATH_INFO'];
        }

        // Split uri to segments
        $this->segments = preg_split("[\\/]", $path_info, -1, PREG_SPLIT_NO_EMPTY);
    }

    /**
     * Search controller class
     */
    private function _set_controller() {

        if (!isset($this->segments[0])) {  // Controller is not set
            require BASEPATH . 'config/config.php';

            // Get Default Controller
            $this->segments[0] = $config['default_controller'];
        }

        $controller_path = BASEPATH . 'controllers/' . $this->segments[0] . '.php';

        if (file_exists($controller_path)) {    // Controller file is exist
            require_once BASEPATH . 'core/controller.php';
            require_once $controller_path;
            $class = ucfirst($this->segments[0] . 'Controller');

            if (!class_exists($class)) {    // Controller class is exist
                show_error("Controller $class could not be found.");
            }

            $this->controller_obj = new $class();
            $this->controller = $this->segments[0];
        } else {
            show_error("File $controller_path could not be found.");
        }
    }

    /**
     * Set Method
     */
    private function _set_method() {
        // If method is not defined, call index
        if (!isset($this->segments[1]))
            $this->segments[1] = 'index';

        if (method_exists($this->controller_obj, $this->segments[1])) {   // Method is exist
            $this->method = $this->segments[1];

            if (substr($this->method, 0, 1) == '_') {  // Method is private
                show_error("Method $this->method could not be found.");
            }
        } else {
            show_error();
        }
    }

    /**
     * Set method's parameter
     */
    private function _set_vars() {
        if (isset($this->segments[2])) {
            $this->vars = array_slice($this->segments, 2);
        }
    }

    /**
     * Do request
     *
     * http://website.com/profile/view/someone
     * Call method <i>view(someone)</i> in <i>class ViewController</i>
     *
     * @return  void
     */
    public function do_request() {
        call_user_func(array(&$this->controller_obj, '_before'));
        call_user_func_array(array(&$this->controller_obj, $this->method), $this->vars);
        call_user_func(array(&$this->controller_obj, '_after'));
    }

    /**
     * Get Segment
     * @return ArrayOfString
     */
    public function get_segment() {
        return $this->segments;
    }

    public function &get_instance() {
        return self::$instance;
    }

}

?>
